#include "StdAfx.h"
#include "NeuronsGroup.h"

using namespace std;
NeuronsGroup::NeuronsGroup(unsigned int inputsQuantity, unsigned int inputsComponents)throw(IllegalArgumentException)
{
	if (inputsQuantity == 0){
		throw IllegalArgumentException("NeuronsGroup Class: inputsQuantity should not be zero");
	}

	if (inputsComponents < 1){
		throw IllegalArgumentException("NeuronsGroup Class: inputsComponents should be more than 1");
	}

	int neuronesQuantity = inputsComponents;
	_neurons.resize(neuronesQuantity);
	for (int i=0; i<neuronesQuantity;i++){
		_neurons[i] = new Neuron(inputsQuantity);
	}

	_output=0;
}


NeuronsGroup::~NeuronsGroup(void)
{
	int ns = _neurons.size();
	for (int i=0;i<ns; i++){
		delete _neurons[i];
	}
}

float NeuronsGroup::getOutput()
{
	return _output;
}

void NeuronsGroup::setInputValues(vector<float> values )
{
	_output = 0;
	for (unsigned int i=0;i<_neurons.size();i++){
		_neurons[i]->setInputsValues(values);
		_neurons[i]->calculateOutput();
		_output+=_neurons[i]->getOutput();
	}
}

std::vector<float> NeuronsGroup::getInputWeights()
{
	vector <float> weights;
	for (unsigned int i=0; i< _neurons.size(); i++){
		for (int j=0; j<_neurons[0]->getInputsQuantity();j++){
			weights.push_back(_neurons[i]->getInputsWeghts()[j]); // X1(x11,x12,...), X2(x21,x22...),...
		}
	}
	return weights;
}

int NeuronsGroup::getWeightsQuantity()
{
	unsigned int w = _neurons[0]->getInputsWeghts().size()*_neurons.size();
	return w;
}

vector<float> NeuronsGroup::getInputValues()
{
	vector<float> inputValues, tmp;
	for (unsigned int i=0;i<_neurons.size();i++){
		tmp = _neurons[i]->getInputsValues();
		inputValues.insert(inputValues.end(),tmp.data(),tmp.data()+tmp.size());
	}
	return inputValues;
}

void NeuronsGroup::setInputWeights( std::vector<float> weights )throw(IllegalArgumentException)
{
	unsigned int weightsQuantity = getWeightsQuantity();
	if (weightsQuantity!=weights.size()){
		throw IllegalArgumentException("NeuronsGroup Class: Input weights quantity is not valid");
	}
	unsigned int neuronsWeightsQuantity = weightsQuantity/_neurons.size();
	vector<float> tmp;
	for (unsigned int i=0; i<_neurons.size(); i++){
		tmp = weights;
		int b = neuronsWeightsQuantity*i;
		tmp.assign(weights.begin()+b,weights.begin()+b+neuronsWeightsQuantity);
		_neurons[i]->setInputsWeights(tmp);
	}
}

void NeuronsGroup::clculateOutput()
{
	for (unsigned int i=0;i<_neurons.size();i++){
		_neurons[i]->calculateOutput();
		_output+=_neurons[i]->getOutput();
	}
}
